package mylog

import (
	"fmt"
	"runtime"
	"runtime/debug"
	"strings"
	"sync"
	"time"
)

type CallStackCache struct {
	mu             sync.RWMutex
	stack          []string
	funcToKeyCache map[string]*Log
	timestamp      time.Time
	ttl            time.Duration
}
type FuncToKeyCache struct {
	mu        sync.RWMutex
	cache     map[string]*Log
	timestamp time.Time
	ttl       time.Duration
}

var callStack = CallStackCache{
	ttl: 5 * time.Minute, // 缓存有效期为5秒
}

var funcKey = FuncToKeyCache{
	ttl: 5 * time.Minute, // 缓存有效期为5秒
}

// 获取调用栈并缓存
func getCachedCallStack() []string {
	callStack.mu.RLock()
	if time.Since(callStack.timestamp) < callStack.ttl {
		// 返回缓存的调用栈
		defer callStack.mu.RUnlock()
		return callStack.stack
	}
	callStack.mu.RUnlock()

	// 缓存过期或未缓存，获取新的调用栈
	stack := GetCallStack()

	// 更新缓存
	callStack.mu.Lock()
	callStack.stack = stack
	callStack.timestamp = time.Now()
	callStack.mu.Unlock()

	return stack
}

// 获取调用栈
func GetCallStack() []string {
	var stackInfo []string
	var stack [32]uintptr
	length := runtime.Callers(0, stack[:])
	for i, pc := range stack[:length] {
		fn := runtime.FuncForPC(pc)
		file, line := fn.FileLine(pc)
		info := fmt.Sprintf("[%d:%s:%d:%s %x]", i, file, line, fn.Name(), fn.Entry())
		println(info)
		stackInfo = append(stackInfo, info)
	}
	return stackInfo
}

func LogInit(keyInfo string) *Log {
	if keyInfo == "" {
		keyInfo = fmt.Sprintln(time.Now().UTC().UnixMicro())
	}
	// stack := getCachedCallStack()
	stackInfo := debug.Stack()
	for i, l := range strings.Split(string(stackInfo), "\n") {
		fmt.Printf("\n %d --- line:%v \n", i, l)
	}
	// for i, s := range stack {
	// 	// fmt.Printf("%d [%v]", i, s)
	// 	if strings.Contains(s, "mylog.LogInit") {
	// 		fmt.Printf("\n func:[%v] stack:[%v] \n", stack[i+1], stack)
	// 		break
	// 	}
	// }
	return NewLogger(keyInfo, nil)
}
